#include "tcpclient.h"
#include "ui_tcpclient.h"
#include <QMessageBox>

TcpClient::TcpClient(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::TcpClient)
{
    ui->setupUi(this);

    TotalBytes = 0;
    bytesReceived = 0;
    fileNameSize = 0;

    tcpClient = new QTcpSocket(this);
    tcpPort = 6666;

    connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readMessage()));
    connect(tcpClient, SIGNAL(errorOccurred(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
}

TcpClient::~TcpClient()
{
    delete ui;
}

void TcpClient::setHostAddress(QHostAddress address)
{
    // 设置远程地址
    hostAddress = address;
    newConnect();
}

void TcpClient::setFileName(QString fileName)
{
    // 打开指定文件，设置描述符
    localFile = new QFile(fileName);
}

void TcpClient::closeEvent(QCloseEvent *)
{
    // 窗口关闭
    on_tcpClientCloseBtn_clicked();
}

void TcpClient::newConnect()
{
    // 新连接
    blockSize = 0;
    tcpClient->abort();
    tcpClient->connectToHost(hostAddress, tcpPort);
    time.start();
}

void TcpClient::readMessage()
{
    // 从tcpsocket读取数据
    QDataStream in(tcpClient);
    in.setVersion(QDataStream::Qt_6_7);

    // 计时结束
    float useTime = time.elapsed();

    // 第一次读取数据
    if (bytesReceived <= sizeof(qint64) * 2) {
        if ((tcpClient->bytesAvailable() >= sizeof(qint64)*2) && (fileNameSize == 0)) {
            in >> TotalBytes; // 数据总大小，读取其中0-7范围的字节
            in >> fileNameSize; // 文件名大小，读取其中8-15范围的字节
            bytesReceived += sizeof(qint64)*2;
        }

        // 读取文件名
        if ((tcpClient->bytesAvailable() >= fileNameSize) && (fileNameSize != 0)) {
            in >> fileName; // 读取文件名，在索引15之后的所有字节
            bytesReceived += fileNameSize;
            if (!localFile->open(QFile::WriteOnly)) {
                QMessageBox::warning(this,tr("应用程序"),tr("无法读取文件 %1:\n%2.").arg(fileName).arg(localFile->errorString()));
                return;
            }
        } else {
            return;
        }
    }

    // 读取文件数据
    if (bytesReceived < TotalBytes) {
        bytesReceived += tcpClient->bytesAvailable();
        inBlock = tcpClient->readAll();
        localFile->write(inBlock);
        inBlock.resize(0);
    }

    ui->progressBar->setMaximum(TotalBytes);
    ui->progressBar->setValue(bytesReceived);

    // 计算单次花费时间
    double speed = bytesReceived / useTime;
    ui->clientStatusLabel->setText(tr("已接收 %1MB (%2MB/s)\n共%3MB 已用时:%4秒\n估计剩余时间：%5秒")
                                          .arg(bytesReceived / (1024*1024))
                                          .arg(speed*1000/(1024*1024),0,'f',2)
                                          .arg(TotalBytes / (1024 * 1024))
                                          .arg(useTime/1000,0,'f',0)
                                          .arg(TotalBytes/speed/1000 - useTime/1000,0,'f',0));
    if (bytesReceived == TotalBytes) {
        localFile->close();
        tcpClient->close();
        ui->clientStatusLabel->setText(tr("接收文件 %1 完毕").arg(fileName));
    }

}

void TcpClient::displayError(QAbstractSocket::SocketError errorr)
{
    qDebug() << errorr;
}

void TcpClient::on_tcpClientCancelBtn_clicked()
{
    // 取消接收
    tcpClient->abort();
    if (localFile->isOpen())
        localFile->close();
}


void TcpClient::on_tcpClientCloseBtn_clicked()
{
    // 关闭窗口
    tcpClient->abort();
    if (localFile->isOpen())
        localFile->close();

    close();
}

